#include "IOIR.h"
#include "ESP8266HTTPClient.h"
#include "ioSerial.h"
#include <FS.h>
#include "ioUserSettings.h"
#include "ioUDP.h"
#include "RCSwitch.h"
#include "ioplatform.h"

#define DOWNLOAD_PREFIX "http://irext-debug.oss-cn-hangzhou.aliyuncs.com/irda_"
#define DOWNLOAD_SUFFIX ".bin"
#define SAVE_PATH "/bin/"

StaticJsonDocument<1024> ac_status_doc;
decode_results results; // Somewhere to store the results
extern StaticJsonDocument<1024> udppack;
void initAC(String file);
void saveAC(String file, t_remote_ac_status status);

HTTPClient http_client;

/************************************************************************
* 函数名称: downLoadFile()
* 输入参数: 无
* 返回值  : 无
* 功    能: 下载解码文件
**********************************************************************/
void downLoadFile(String file)
{
    String download_url = DOWNLOAD_PREFIX + file + DOWNLOAD_SUFFIX;
    String save_path = SAVE_PATH + file;

    File cache = SPIFFS.open(save_path, "w");
    if (cache)
    {
        WiFiClient wifi_client;
        http_client.begin(wifi_client, download_url);
        if (HTTP_CODE_OK == http_client.GET())
        {
            DEBUGF("Download %s success\n", file.c_str());
            http_client.writeToStream(&cache);
        }
        else
        {
            SPIFFS.remove(save_path);
            DEBUGF("Download %s failed\n", file.c_str());
        }
    }
    else
    {
        ERRORLN("Don't have enough file zoom");
    }
    cache.close();
}
/************************************************************************
* 函数名称: sendStatus()
* 输入参数: 无
sendStatus* 返回值  : 无
* 功    能: 发送遥控器编码数据
**********************************************************************/
void sendStatus(String file, t_remote_ac_status status)
{
    String save_path = SAVE_PATH + file;
    if (!SPIFFS.exists(save_path))
    {
        downLoadFile(file);
    }

    if (SPIFFS.exists(save_path))
    {
        File cache = SPIFFS.open(save_path, "r");
        if (cache)
        {
            UINT16 content_size = cache.size();
            DEBUGF("content size = %d\n", content_size);

            if (content_size != 0)
            {
                UINT8 *content = (UINT8 *)malloc(content_size * sizeof(UINT8));
                cache.seek(0L, fs::SeekSet);
                cache.readBytes((char *)content, content_size);
                ir_binary_open(REMOTE_CATEGORY_AC, 1, content, content_size);
                UINT16 *user_data = (UINT16 *)malloc(512 * sizeof(UINT16));
                UINT16 data_length = ir_decode(0, user_data, &status, FALSE);

                IO_DEBUG.println();
                //DEBUGF("data_length = %d\n", data_length);
                //for (int i = 0; i < data_length; i++)
                //{
                //    IO_DEBUG.printf("%d ", *(user_data + i));
                //}
                pilot_set(1,0);
                IO_DEBUG.println();
                DEBUGF("send = %d\n", data_length);
                ir_send->sendRaw(user_data, data_length, 38);
                DEBUGF("send_com = %d\n", data_length);
                ir_close();
                pilot_set(0,0);
                free(user_data);
                free(content);
            }
            else
            {
                ERRORF("Open %s is empty\n", save_path.c_str());
            }
        }
        cache.close();
    }
    saveAC(file, status);
}

/************************************************************************
* 函数名称: showIRProtocol()
* 输入参数: 无
* 返回值  : 无
* 功    能: 接收到的数据显示编码类型
**********************************************************************/
void showIRProtocol(decode_results *results)
{
    Serial.print("Protocol: ");
    //
    switch (results->decode_type)
    {
    case NEC:
        Serial.print("NEC");
        break;
    case SONY:
        Serial.print("SONY");
        break;
    case RC5:
        Serial.print("RC5");
        break;
    case RC6:
        Serial.print("RC6");
        break;
    default:
        Serial.print("Unknown encoding");
        return;
    }
    //
    Serial.print("irCode: ");
    Serial.printf("value:%x\n", results->value); //

    udppack.clear();
    udppack["cmd"] = "irres";
    udppack["value"] = results->value;
    udppack["irtype"] = (int)(results->decode_type);
    udppack["bits"] = (int)(results->bits);
    IPAddress ip(255, 255, 255, 255);
    sendUDP(&udppack, ip);
}

/************************************************************************
* 函数名称: recvRaw()
* 输入参数: 无
* 返回值  : 无
* 功    能: 红外数据接收
**********************************************************************/
void recvRaw()
{
    static uint64_t rfpretime = 0;
    if (mySwitch.available())
    {
        Serial.print("Received ");
        if ((millis() - rfpretime) > 300)
        {
            Serial.print("Received ");
            Serial.print(mySwitch.getReceivedValue());
            Serial.print(" / ");
            Serial.print(mySwitch.getReceivedBitlength());
            Serial.print("bit ");
            Serial.print("Protocol: ");
            Serial.println(mySwitch.getReceivedRawdata()[0]);
           
            udppack.clear();
            udppack["cmd"] = "rfres";
            udppack["value"] = mySwitch.getReceivedValue();
            udppack["irtype"] = mySwitch.getReceivedProtocol();
            udppack["bits"] = mySwitch.getReceivedBitlength();
             udppack["width"] = mySwitch.getReceivedRawdata()[0]/31;
            IPAddress ip(255, 255, 255, 255);
            sendUDP(&udppack, ip);
        }
        mySwitch.resetAvailable();
        rfpretime = millis();
    }
    if (ir_recv->decode(&results))
    {
        showIRProtocol(&results);
        //saveRaw();
        ir_recv->resume();
    }
}

/************************************************************************
* 函数名称: initAC()
* 输入参数: 无
* 返回值  : 无
* 功    能: 初始化空调遥控器数据
**********************************************************************/
void initAC(String file)
{
    ac_status_doc[file]["power"] = 0;
    ac_status_doc[file]["temperature"] = 8;
    ac_status_doc[file]["mode"] = 2;
    ac_status_doc[file]["swing"] = 0;
    ac_status_doc[file]["speed"] = 0;
}
/************************************************************************
* 函数名称: initAC()
* 输入参数: 无
* 返回值  : 无
* 功    能: 初始化空调遥控器数据
**********************************************************************/
t_remote_ac_status getACState(String file)
{
    if (!ac_status_doc.containsKey(file))
    {
        initAC(file);
    }
    t_remote_ac_status status;
    int power = ac_status_doc[file]["power"];
    int temperature = ac_status_doc[file]["temperature"];
    int mode = ac_status_doc[file]["mode"];
    int swing = ac_status_doc[file]["swing"];
    int wind_speed = ac_status_doc[file]["speed"];
    status.ac_power = (t_ac_power)power;
    status.ac_temp = (t_ac_temperature)temperature;
    status.ac_mode = (t_ac_mode)mode;
    status.ac_swing = (t_ac_swing)swing;
    status.ac_wind_speed = (t_ac_wind_speed)wind_speed;
    return status;
}

/************************************************************************
* 函数名称: saveAC()
* 输入参数: 无
* 返回值  : 无
* 功    能: 暂存遥控器数据
**********************************************************************/
void saveAC(String file, t_remote_ac_status status)
{
    ac_status_doc[file]["power"] = status.ac_power;
    ac_status_doc[file]["temperature"] = status.ac_temp;
    ac_status_doc[file]["mode"] = status.ac_mode;
    ac_status_doc[file]["swing"] = status.ac_swing;
    ac_status_doc[file]["speed"] = status.ac_wind_speed;
}